/*
 * @Descripttion:
 * @version:
 * @Author: lfzxs@qq.com
 * @Date: 2023-11-09 15:44:29
 * @LastEditors: lfzxs@qq.com
 * @LastEditTime: 2023-12-08 15:13:27
 */
/*
 * @Descripttion:
 * @version:
 * @Author: lfzxs@qq.com
 * @Date: 2023-11-09 15:44:29
 * @LastEditors: lfzxs@qq.com
 * @LastEditTime: 2023-12-01 15:38:48
 */
package libService

import (
	"context"
	"fmt"

	"gitee.com/g_boot/chkboot-common/library/liberr"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
)

type IDao interface {
	List(ctx context.Context, pageQuery *PageInp) (res *PageModel, err error)
	Search(ctx context.Context, querObject any) (res *PageModel, err error)
	Add(ctx context.Context, object any) (recordid string,err error) 
	Delete(ctx context.Context,delObject any)(err error)
}

type BaseDao[T any] struct {
	//表名
	Table string
}

func (obj *BaseDao[T]) Search(ctx context.Context, querObject any) (res *PageModel, err error) {
	var (
		pgeinput PageInp
	)

	ServiceUtil.MakeQueryAndOrderWrapper(querObject, &pgeinput)

	model, err := obj.List(ctx, &pgeinput)

	return model, err
}

func (obj *BaseDao[T]) List(ctx context.Context, pageQuery *PageInp) (res *PageModel, err error) {
	var (
		data   []T
		result PageModel
	)

	oper := g.Model(obj.Table).Safe().Ctx(ctx)
	oper = ServiceUtil.MakeWhereAndOrder(oper, pageQuery)

	result.Total, err = oper.Count()
	if err != nil {
		err = gerror.Wrap(err, liberr.ErrorORM)
		return nil, err
	}

	err = oper.Scan(&data)

	if err != nil {
		err = gerror.Wrap(err, liberr.ErrorORM)
		return nil, err
	}

	result.List = data
	result.Size = len(data)

	return &result, err
}

func (obj *BaseDao[T]) Add(ctx context.Context, object any) (recordid string,err error) {
	oper := g.Model(obj.Table).Safe().Ctx(ctx)
	adt := ServiceUtil.MakeAddWrapper(object)
	SqlResult,err := oper.Data(adt.Model).Insert()
	if(err != nil){
		return "",err
	}
	
	if value, ok := adt.Model["recordId"]; ok {
		recordid = fmt.Sprintf("%s",value)
	}else{
		lastid,err1 := SqlResult.LastInsertId()
		if(nil == err1){
			recordid = fmt.Sprintf("%x",lastid) 
		}
	}


	return recordid, err
}

func (obj *BaseDao[T]) Edit(ctx context.Context, object any) (err error) {
	oper := g.Model(obj.Table).Safe().Ctx(ctx)
	adt := ServiceUtil.MakeEditWrapper(object)
	oper = ServiceUtil.MakeWhere(oper,&adt.QueryWrapper)
	oper.Update(adt.Model)
	return
}


func (obj *BaseDao[T]) Update(ctx context.Context, condition any, object any) (err error) {
	return
}

func (obj *BaseDao[T]) Delete(ctx context.Context,delObject any)(err error){
	oper := g.Model(obj.Table).Safe().Ctx(ctx)
	adt := ServiceUtil.MakeDeleteWrapper(delObject)

	oper = ServiceUtil.MakeWhere(oper,&adt)

	_,err = oper.Delete()

	return 
}

func (obj *BaseDao[T]) Get(ctx context.Context,queryObject any)(entity *T,err error){
	adt := ServiceUtil.MakeQueryWrapper(queryObject)
	return obj.Query(ctx,adt)
}

func (obj *BaseDao[T]) Query(ctx context.Context,adt QueryWrapper)(entity *T,err error){
	var (
		data   *T
	)
	oper := g.Model(obj.Table).Safe().Ctx(ctx)
	oper = ServiceUtil.MakeWhere(oper,&adt)

	err = oper.Scan(&data)

	if err != nil {
		err = gerror.Wrap(err, liberr.ErrorORM)
		return nil, err
	}

	return data,err
}

